package com.notepad.blog.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.notepad.blog.common.exception.ApiAsserts;
import com.notepad.blog.domain.BmsPost;
import com.notepad.blog.domain.BmsPostTag;
import com.notepad.blog.domain.BmsTag;
import com.notepad.blog.domain.UmsUser;
import com.notepad.blog.domain.dto.CreatePostDTO;
import com.notepad.blog.domain.vo.PostVO;
import com.notepad.blog.domain.vo.ProfileVO;
import com.notepad.blog.mapper.BmsPostMapper;
import com.notepad.blog.mapper.BmsPostTagMapper;
import com.notepad.blog.mapper.BmsTagMapper;
import com.vdurmont.emoji.EmojiParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName BmsPostService
 * @description:
 * @author: 一粒麦子
 * @Date 2021/2/13 12:44
 **/
@Service
public class BmsPostService extends ServiceImpl<BmsPostMapper, BmsPost> {

    @Autowired
    private BmsPostMapper postMapper;

    @Autowired
    private UmsUserService userService;

    @Autowired
    private BmsTagMapper tagMapper;

    @Autowired
    private BmsTagService tagService;

    @Autowired
    private BmsPostTagService postTagService;

    /**
     * 查询文章列表
     *
     * @param pageNo
     * @param pageSize
     * @param tab
     * @return
     */
    public Page<PostVO> getList(Integer pageNo, Integer pageSize, String tab) {
        Page<PostVO> page = new Page(pageNo, pageSize);
        // 查询文章
        Page<PostVO> iPage = postMapper.selectListAndPage(page, tab);
        return iPage;
    }

    /**
     * 保存文章
     *
     * @param userName
     * @param createPostDTO
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public BmsPost createPost(String userName, CreatePostDTO createPostDTO) {
        // 获取用户
        UmsUser loginUser = userService.getOne(
                new LambdaQueryWrapper<UmsUser>().eq(UmsUser::getUsername, userName)
        );

        if (ObjectUtils.isNull(loginUser)) {
            ApiAsserts.fail("用户不存在");
        }

        // 保存
        BmsPost post = BmsPost.builder()
                .userId(loginUser.getId())
                .title(createPostDTO.getTitle())
                .content(createPostDTO.getContent())
                .createTime(new Date())
                .build();
        this.save(post);

        // 给用户增加积分+1
        userService.updateById(loginUser.setScore(loginUser.getScore() + 1));

        // 保存标签,postTag中间表(先查询是否存在)
        this.saveTagAndPostTag(createPostDTO, post);

        return post;
    }

    /**
     * 标签
     *
     * @param createPostDTO
     * @param post
     */
    private void saveTagAndPostTag(CreatePostDTO createPostDTO, BmsPost post) {
        // 保存标签(先查询是否存在)
        for (String tag : createPostDTO.getTags()) {
            BmsTag bmsTag = tagMapper.selectOne(
                    new LambdaQueryWrapper<BmsTag>().eq(BmsTag::getName, tag)
            );

            //如果不存在，保存
            if (ObjectUtils.isNull(bmsTag)) {
                bmsTag = new BmsTag();
                bmsTag.setName(tag);
                bmsTag.setPostCount(1);
                tagMapper.insert(bmsTag);
            } else {// 否存 + 1
                tagMapper.updateById(bmsTag.setPostCount(bmsTag.getPostCount() + 1));
            }
            // 保存post_tag
            postTagService.save(BmsPostTag.builder().postId(post.getId()).tagId(bmsTag.getId()).build());
        }
    }

    public Map<String, Object> getPostById(String id) {
        HashMap<String, Object> map = new HashMap<>(16);
        // 查询文章
        BmsPost post = this.getById(id);
        Assert.notNull(post, "当前文章不存在，或被删除");
        // 查看 +1
        post.setView(post.getView() + 1);
        this.updateById(post);
        // 表情转码
        post.setContent(EmojiParser.parseToUnicode(post.getContent()));
        map.put("topic", post);
        // 文章的标签
        // 标签
        QueryWrapper<BmsPostTag> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(BmsPostTag::getPostId, post.getId());
        Set<String> set = new HashSet<>();
        for (BmsPostTag articleTag : postTagService.list(wrapper)) {
            set.add(articleTag.getTagId());
        }
        List<BmsTag> tags = tagService.listByIds(set);
        map.put("tags", tags);

        // 作者
        ProfileVO user = userService.getUserProfile(post.getUserId());
        map.put("user", user);

        return map;
    }

    /**
     * 随便看看
     *
     * @param id
     * @return
     */
    public List<BmsPost> getRecommend(String id) {
        return postMapper.getRecommend(id);
    }

    public BmsPost updateById(String userName, BmsPost post) {
        System.out.println("post.getTags() = " + post.getTags());

        // 获取用户信息
        UmsUser umsUser = userService.getOne(new LambdaQueryWrapper<UmsUser>().eq(UmsUser::getUsername, userName));
        Assert.notNull(umsUser, "用户不存在");
        Assert.isTrue(umsUser.getId().equals(post.getUserId()), "非本人无权修改");
        post.setModifyTime(new Date());
        post.setContent(EmojiParser.parseToAliases(post.getContent()));
        this.updateById(post);

        // 修改标签(先删除，然后保存)
//        postTagService.remove(new LambdaQueryWrapper<BmsPostTag>().eq(BmsPostTag::getPostId, post.getId()));
//        //保存
//        saveTagAndPostTag(null,null);

        return post;
    }

    public void deleteById(String userName, String id) {
        UmsUser umsUser = userService.getOne(new LambdaQueryWrapper<UmsUser>().eq(UmsUser::getUsername, userName));
        Assert.notNull(umsUser, "用户不存在");
        BmsPost post = this.getById(id);
        Assert.notNull(post, "来晚一步，话题已不存在");
        Assert.isTrue(post.getUserId().equals(umsUser.getId()), "你为什么可以删除别人的话题？？？");
        this.removeById(id);
    }

    /**
     * 搜索
     * @param keyword
     * @param page
     * @return
     */
    public Page<PostVO> searchByKey(String keyword, Page<PostVO> page) {
        // 查询话题
        Page<PostVO> iPage = this.baseMapper.searchByKey(page, keyword);
        // 查询话题的标签
//        setTopicTags(iPage);
        return iPage;
    }

//    private void setTopicTags(Page<PostVO> iPage) {
//        iPage.getRecords().forEach(topic -> {
//            List<BmsPostTag> topicTags = postTagService.selectByTopicId(topic.getId());
//            if (!topicTags.isEmpty()) {
//                List<String> tagIds = topicTags.stream().map(BmsPostTag::getTagId).collect(Collectors.toList());
//                List<BmsTag> tags = tagMapper.selectBatchIds(tagIds);
//                topic.setTags(tags);
//            }
//        });
//    }
}
